/*
    SUSAN® - Sole of Unix Save ANything

      Copyright (C) 2011-2016 Skyatlas Co. LTD

   

   
*/
/*
 * Kern Sibbald, May MM, major revision December MMIII
 */
/**
 * @file
 * SUSAN scheduler
 *
 * It looks at what jobs are to be run and when
 * and waits around until it is time to
 * fire them up.
 */

#include "include/susan.h"
#include "dird.h"
#include "dird/dird_globals.h"
#include "dird/scheduler.h"
#include "dird/scheduler_private.h"
#include "dird/scheduler_time_adapter.h"
#include "dird/jcr_private.h"
#include "dird/job.h"
#include "dird/storage.h"
#include "include/make_unique.h"
#include "lib/parse_conf.h"

class JobControlRecord;

namespace directordaemon {

class JobResource;
class SchedulerTimeAdapter;

static constexpr int debuglevel = 200;

Scheduler& Scheduler::GetMainScheduler() noexcept
{
  static Scheduler scheduler;
  return scheduler;
}

Scheduler::Scheduler() noexcept : impl_(std::make_unique<SchedulerPrivate>()){};

Scheduler::Scheduler(std::unique_ptr<SchedulerTimeAdapter> time_adapter,
                     std::function<void(JobControlRecord*)> ExecuteJob) noexcept
    : impl_(std::make_unique<SchedulerPrivate>(std::move(time_adapter),
                                               std::move(ExecuteJob)))
{
  // constructor used for tests to inject mocked time adapter and callbacks
}

Scheduler::~Scheduler() = default;

void Scheduler::AddJobWithNoRunResourceToQueue(JobResource* job,
                                               JobTrigger job_trigger)
{
  impl_->AddJobWithNoRunResourceToQueue(job, job_trigger);
}

void Scheduler::Run()
{
  while (impl_->active) {
    Dmsg0(debuglevel, "Scheduler Cycle\n");
    impl_->FillSchedulerJobQueueOrSleep();
    impl_->WaitForJobsToRun();
  }
}

void Scheduler::Terminate()
{
  impl_->active = false;
  impl_->time_adapter->time_source_->Terminate();
}

void Scheduler::ClearQueue() { impl_->prioritised_job_item_queue.Clear(); }

} /* namespace directordaemon */
